#include "precompiled.h"
#include "Common.h"
#include "World_Manager.h"
#include "Core.h"
#include "Scenery.h"
#include "Player.h"
#include "ParticleManager.h"

#define TEST_WORLD		"../worlds/wtest_1.world"
//#define TEST_WORLD		"../worlds/wtest_1_monkeybomb.world"

#define GUN_LASER_RIFLE "../models/OBJ/FuturisticGun.obj"
#define GUN_LASER_DEAGLE "../models/OBJ/deagle_single.obj"
#define GUN_LASER_BLASTER "../models/OBJ/mblaster.obj"

const float PARTICLE_VELOCITY_SHOT = 0.005f;
const float PARTICLE_ACCELERATION_SHOT = 0.002f;

stack<Scenery*> World_Manager::async_requestRigidbodies_Scenery;
Player*	World_Manager::player;


void dbg_create_particles(){
	ParticleBehavior behavior;
	behavior.behavior_type = LINEAR;
	behavior.maxVelocity = PARTICLE_VELOCITY_SHOT * 10.0f;
	behavior.noisy = true;
	behavior.physical = true;
	behavior.acceleration = PARTICLE_ACCELERATION_SHOT;
	behavior.origin = glm::vec3(-100.0f, 20.0f, 0.0f);
	behavior.start = behavior.origin;
	behavior.end = glm::vec3(100.0f, 20.0f, 0.0f);

	ParticleManager::CreateEmitter(PS32,behavior,"dbg");
	//ParticleManager::RunParticles("dbg");
}
void dbg_update_particles( GLdouble time ){
	ParticleManager::Update( time );
}


// Get a reference to the player camera.
Camera_Alt const * World_Manager::GetPlayereCamera(){
	return player->getCamera();
}

World_Manager::World_Manager(void){
	initialize();
}
World_Manager::~World_Manager(void){

}

void World_Manager::initialize(){
	player = 0;
	CreatePlayer();
	Dbg_InitWorld();
}

void World_Manager::load_world_from_dot( const char* path ){
	gs_assetIO.load_dot_world( path );

	std::queue<WORLD_SCENERY_ORDER> wso_q;
	gs_assetIO.Get_WorldSceneOrder( wso_q );

	while( !wso_q.empty() ){
		add_Scenery( wso_q.front() );
		wso_q.pop();
	}
}


void World_Manager::CreatePlayer(){
	if( player == 0 )
		player = new Player();
}

void World_Manager::Init_Player(){
}


glm::mat4* World_Manager::GetCurrentCamera(  ){
	return player->getCameraMatrix();
}

void World_Manager::Update( GLdouble time ){

	// Update our objects.
	player->Update( time );
	for( int c = 0; c < scenery.size(); c++ ){
		if( !scenery.at( c )->didDeath() )
			scenery.at( c )->Update( time );
	}

	// Particles.
	dbg_update_particles( time );
}

void World_Manager::SubmitToFrame( glm::mat4 &projview ){
	player->Draw();

	for( int c = 0; c < scenery.size(); c++ )
		scenery.at( c )->Draw( projview, player->getCamera() );
}

void World_Manager::add_Scenery( WORLD_SCENERY_ORDER &wso ){

	scenery.push_back( new Scenery( wso.model_key, wso.isStatic ) );
	scenery.at( scenery.size() - 1 )->setFlashable( wso.isFlashable );
	scenery.at( scenery.size() - 1 )->Initial_Translate( wso.transform._translation );
	scenery.at( scenery.size() - 1 )->Initial_Rotate( wso.transform._rotation );
	scenery.at( scenery.size() - 1 )->Initial_Scale( wso.transform._scale );

	if( !wso.isStatic)
		async_requestRigidbodies_Scenery.push( scenery.at( scenery.size() - 1 ) );
}


void World_Manager::Clear_Scenery(){
	scenery.clear();
}
void World_Manager::Clear_Player(){
	delete player;
}

void World_Manager::Dbg_InitWorld(){
	load_world_from_dot( TEST_WORLD );

	//gs_assetIO.load_model_to_pool( GUN_LASER_RIFLE, "gun_laser_rifle" );
	gs_assetIO.load_model_to_pool( GUN_LASER_DEAGLE, "gun_laser_deagle" );
	gs_assetIO.load_model_to_pool( GUN_LASER_BLASTER, "gun_laser_blaster" );

	dbg_create_particles();
}

void World_Manager::Dbg_DrawScenery( glm::mat4 &projview ){}
